package com.leon.document_auto_generation_tool.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Future;
import java.util.stream.Collectors;


/**
 * @author XZG
 * @creatTime 2023-03-17
 * <p>
 * 【多线程服务类】使用 @Async 定义一个异步线程任务
 * Future 泛型接口，用来接收任务执行结果，如果不要返回值只需要把方法改为void返回即可
 */
@Component
public class ThreadService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ThreadService.class);

    @Resource
    private Executor asyncServiceExecutor;

    /**
     * 最重要的方法，通过 stream 结合线程池和 RestTemplate 批量请求，并统计结果
     *
     * @param list
     * @return
     */
    public List<Integer> streamTest(ArrayList<Integer> list) {
        // 通过 stream 结合线程池和 RestTemplate 批量请求，并统计结果
//        List<CompletableFuture<PriceResult>> completableFutures = list.stream()
        List<CompletableFuture<Integer>> completableFutures = list.stream()
                .map(i -> CompletableFuture.supplyAsync(() -> i + 1, asyncServiceExecutor))
                .collect(Collectors.toList());
        // 在独立的流中，等待所有并行处理结束，做最终结果处理
        return completableFutures.stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList());
    }


    public List<Integer> handleTest(ArrayList<Integer> list) {
        // 先触发各自平台的并行处理
//        List<CompletableFuture<PriceResult>> completableFutures = list.stream()
        List<CompletableFuture<Integer>> completableFutures = list.stream()
                .map(i -> CompletableFuture.supplyAsync(() -> {
//            int i = 10 / 0;
                    return new Random().nextInt(10);
                }, asyncServiceExecutor).handle((param, throwable) -> {
                    int result = -1;
                    if (throwable == null) {
                        result = param * 2;
                    } else {
                        LOGGER.info("exception:", throwable);
                    }
                    return result;
                }))
                .collect(Collectors.toList());
        // 在独立的流中，等待所有并行处理结束，做最终结果处理
        return completableFutures.stream()
                .map(CompletableFuture::join)
                .collect(Collectors.toList());
    }

    public void whenComplete(ArrayList<Integer> list) throws Exception {
        CompletableFuture.supplyAsync(() -> {
//            int i = 10 / 0;
            return new Random().nextInt(10);
        }, asyncServiceExecutor).whenCompleteAsync((o, t) -> {
            if (t != null) {
                LOGGER.error("exception:", t);
            } else {
                list.add(o);
            }
        });
    }

    public void accept(ArrayList<Integer> list) throws Exception {
        CompletableFuture.supplyAsync(() -> {
//            int i = 10 / 0;
            return new Random().nextInt(10);
        }, asyncServiceExecutor).handle((param, throwable) -> {
            int result = -1;
            if (throwable == null) {
                result = param * 2;
            } else {
                LOGGER.error("exception:", throwable);
            }
//            return result;
            return result;
        }).thenAcceptAsync(o -> list.add(o));
    }

    public void handle(ArrayList<Integer> list) throws Exception {
        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            int i = 10 / 0;
            return new Random().nextInt(10);
        }, asyncServiceExecutor).handle((param, throwable) -> {
            int result = -1;
            if (throwable == null) {
                result = param * 2;
            } else {
                LOGGER.info("exception:", throwable);
            }
//            return result;
            return result;
        });
//        }).thenAccept(o -> );
//        System.out.println(future.get());
        list.add(future.get());
    }

    @Async
    public Future<String> asyncTask1(Integer i) {
        // 返回值
        String result1 = "";
        try {
            LOGGER.info("任务1：进程" + i + "开始>>");
            Thread.sleep(2000);//任务一模拟耗时2秒
            LOGGER.info("任务1：进程" + i + "结束");
            result1 = "任务1：进程" + i + "返回结果[]";
        } catch (InterruptedException ex) {
            LOGGER.info("任务1：进程" + i + "错误：" + ex.getMessage());
        }
        //返回线程执行结果
        return new AsyncResult<String>(result1);
    }

    @Async//异步任务二
    public Future<String> asyncTask2(Integer i) {
        String result2 = "";
        try {
            LOGGER.info("任务2：进程" + i + "开始>>");
            Thread.sleep(1000);//任务二模拟耗时1秒
            LOGGER.info("任务2：进程" + i + "结束");
            result2 = "任务2：进程" + i + "返回结果[]";
        } catch (InterruptedException ex) {
            LOGGER.info("任务2：进程" + i + "错误：" + ex.getMessage());
        }
        return new AsyncResult<String>(result2);
    }
}
